#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include "Util.h"
#include "Polling.h"
#include "Keyboard.h"
#include <signal.h>
#include <fcntl.h>

using namespace std;

int fs_sockFD, fs_connectFD;

struct sockaddr_in fs_serverAddress, fs_clientAddress;

char policy[500];

void startFlashSecurityServer()
{
    bzero(policy, 500);
    strcpy(policy, "<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>");


    fs_connectFD = 0;
    fs_sockFD = socket(AF_INET, SOCK_STREAM, 0);

    if (fs_sockFD < 0)
    {
    	cout << "Error opening socket." << endl;
exit(-1);
	}

    fs_serverAddress.sin_family = AF_INET;
    fs_serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);

    unsigned short port = 843;
    endianSwap(port);

    fs_serverAddress.sin_port = port;

    if (bind(fs_sockFD, (struct sockaddr *) &fs_serverAddress, sizeof(struct sockaddr_in)) < 0)
    {
        cout << "Error binding to socket for port." << port << strerror(errno) << endl;
        exit(-2);
    }

    listen(fs_sockFD, 5);

    socklen_t len = sizeof(fs_clientAddress);
    cout << "Listening and accepting Flash Security requests on port 843..." << endl;

    while (true)
    {
        if (pollRead(fs_sockFD))
        {
            fs_connectFD = accept(fs_sockFD, (struct sockaddr *) &fs_clientAddress, &len);

            cout << "Flash Security Connection made." << endl;

            if (fs_connectFD < 0)
            {
                cout << "Error occurred accepting connection. " << endl;
                exit(-3);
            }
        }

        if (fs_connectFD && pollRead(fs_connectFD))
        {
            char buffer[16000];
            bzero(buffer, 16000);

            int n = read(fs_connectFD, buffer, 16000);

            if (n)
            {
                cout << buffer << endl;
            }
            if (n && strcmp(buffer, "<policy-file-request/>") == 0)
            {
                cout << "Sending policy file." << endl;

                policy[strlen(policy)] = 0;
                write(fs_connectFD, policy, strlen(policy) + 1);
            }
            else
            {
                cout << "Flash Security connection failed." << endl;
                fs_connectFD = 0;
            }
        }

        sleep(1);
    }
}

int main(int argc, char **argv)
{
    cout << "Starting Flash Security Service." << endl;
    cout << "Starting server on port: 843" << endl;

    daemonize();

    startFlashSecurityServer();    
}
